import React, { useCallback, useMemo, useState } from "react"
import { Button, Input } from "@/components/ui"

interface ChildProps {
    user: {
        name: string,
        age: number
    },
    handleClick: (age: number) => void
}

// React.memo 只有当子组件的 props 发生改变时，才会重新渲染
// React.FC<T> 函数式组件类型
const Child: React.FC<ChildProps> = React.memo((props) => {
    console.log('子级 render');
    return <>
        <h2 className="font-bold text-3xl">子级</h2>
        <p>姓名: {props.user.name}  年龄: {props.user.age}</p>
        <Button onClick={() => props.handleClick(22)}>Click me</Button>
    </>
})

export const CacheComponent = () => {

    const [input, setInput] = useState('')
    const [user, setUser] = useState({
        name: '张三',
        age: 18,
    })

    // useMemo 只有当依赖项发生改变时，才会重新计算， 依赖项跟 useEffect 一样
    const total = useMemo(() => {
        console.log('useMemo');
        return user.age
    }, [user.age])

    // useCallback 用于缓存函数，只有依赖项发生改变时，才会重新创建函数
    // 若不添加useCallback 或者 该hook的 依赖项，每次渲染都会创建新的函数，导致子组件 props 变化造成子组件 也重新渲染
    const handleClick = useCallback((value: number = 20) => {
        setUser({ ...user, age: value })
    }, [user])

    return <>
        <h2 className="font-bold text-4xl">父级: {total}</h2>
        <Input value={input} onChange={(e) => setInput(e.target.value)} />
        <Button onClick={() => handleClick()}>Click me</Button>
        <Child user={user} handleClick={handleClick} />
    </>
}